package com.powerteam.service.sys.impl;

import com.alibaba.fastjson.JSON;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.powerteam.exception.BusinessException;
import com.powerteam.mapper.sys.RoleMapper;
import com.powerteam.model.sys.Role;
import com.powerteam.model.sys.RoleMenu;
import com.powerteam.model.sys.RoleUser;
import com.powerteam.model.sys.User;
import com.powerteam.service.sys.RoleService;
import com.powerteam.util.ObjToListUtil;
import com.powerteam.vo.Result;
import com.powerteam.vo.sys.QueryRoleUserVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.List;

/**
 * 角色相关服务接口实现
 *
 * @author jinming.zhang
 * @version 0.0.1
 * @date 2021/12/30
 */
@Slf4j
@Service
public class RoleServiceImpl implements RoleService {

    private final static String CLASS_NAME = "RoleServiceImpl";

    @Autowired
    private RoleMapper roleMapper;

    /**
     * 查询所有角色
     *
     * @return
     */
    @Override
    public List<Role> findAll() {

        try {

            List<Role> roleList = roleMapper.findAll();
            log.info("{} 查询所有角色列表 结果0:{}", CLASS_NAME, JSON.toJSON(roleList));

            return roleList;
        } catch (Exception e) {
            log.warn("{} 查询所有角色列表异常", CLASS_NAME);
            log.error(e.getMessage(), e);
            return new ArrayList<>();
        }
    }

    /**
     * 检查角色名称是否重复
     *
     * @param role
     * @return
     */
    @Override
    public Result checkRoleName(Role role) {

        try {

            Boolean existRoleName = roleMapper.existRoleName(role);
            log.info("{} checkRoleName 检查角色名称是否重复 入参0:{} 结果0:{}", CLASS_NAME, JSON.toJSON(role), existRoleName);

            return new Result(!existRoleName);
        } catch (Exception e) {
            log.warn("{} checkRoleName 检查角色名称是否重复异常 入参0:{}", CLASS_NAME, JSON.toJSON(role));
            log.error(e.getMessage(), e);
            return new Result();
        }
    }

    /**
     * 新增角色
     *
     * @param role
     * @return
     */
    @Override
    @Transactional(rollbackFor = {BusinessException.class}, propagation = Propagation.REQUIRED)
    public Result insert(Role role) {

        try {

            if (!checkRoleName(role).isSuccess()) {
                return new Result(false, "角色名称已存在");
            }

            role.setIsSystemRole(false);
            boolean result = roleMapper.insert(role) > 0;
            log.info("{} insert 新增角色 入参0:{} 结果0:{}", CLASS_NAME, JSON.toJSON(role), result);

            return new Result(result);
        } catch (Exception e) {
            log.warn("{} insert 新增角色异常 入参0:{}", CLASS_NAME, JSON.toJSON(role));
            log.error(e.getMessage(), e);
            throw new BusinessException("新增角色失败");
        }

    }

    /**
     * 批量删除角色
     *
     * @param ids 角色Id列表
     * @return
     */
    @Override
    @Transactional(rollbackFor = {BusinessException.class}, propagation = Propagation.REQUIRED)
    public Result deleteByIds(List<Integer> ids) {

        try {

            boolean result = roleMapper.deleteByIds(ids) > 0;
            log.info("{} deleteByIds 批量删除角色 入参0:{} 结果0:{}", CLASS_NAME, JSON.toJSON(ids), result);

            return new Result(result);
        } catch (Exception e) {
            log.warn("{} deleteByIds 批量删除角色异常 入参0:{}", CLASS_NAME, JSON.toJSON(ids));
            log.error(e.getMessage(), e);
            throw new BusinessException("删除角色失败");
        }
    }

    /**
     * 根据角色Id获取角色信息
     *
     * @param roleId
     * @return
     */
    @Override
    public Role findById(Integer roleId) {

        try {

            Role role = roleMapper.findById(roleId);
            log.info("{} findById 根据角色Id获取角色信息 入参0:{} 结果0:{}", CLASS_NAME, roleId, JSON.toJSON(role));

            return role;
        } catch (Exception e) {
            log.warn("{} findById 根据角色Id获取角色信息异常 入参0:{}", CLASS_NAME, roleId);
            log.error(e.getMessage(), e);
            return new Role();
        }
    }

    /**
     * 更新角色
     *
     * @param role
     * @return
     */
    @Override
    @Transactional(rollbackFor = {BusinessException.class}, propagation = Propagation.REQUIRED)
    public Result update(Role role) {

        try {

            boolean result = roleMapper.update(role) > 0;
            log.info("{} update 更新角色 入参0:{} 结果0:{}", CLASS_NAME, JSON.toJSON(role), result);

            return new Result(result);
        } catch (Exception e) {
            log.warn("{} update 更新角色异常 入参0:{}", CLASS_NAME, JSON.toJSON(role));
            log.error(e.getMessage(), e);
            throw new BusinessException("更新角色失败");
        }
    }

    /**
     * 查询在某角色中的用户列表(分页)
     *
     * @param vo
     * @return
     */
    @Override
    public PageInfo<User> findUserInRole(QueryRoleUserVO vo) {

        try {

            // 处理入参
            if (StringUtils.isEmpty(vo.getDisablePaging()) || !vo.getDisablePaging()) {
                PageHelper.startPage(vo.getPageNum(), vo.getPageSize());
            }
            vo.setWord(StringUtils.isEmpty(vo.getWord()) ? null : "%" + vo.getWord() + "%");
            List<User> userInRole = roleMapper.findUserInRole(vo);
            log.info("{} findUserInRole 查询在某角色中的用户列表(分页) 入参0:{} 结果0:{}", CLASS_NAME, JSON.toJSON(vo), JSON.toJSON(userInRole));

            return new PageInfo<>(userInRole);
        } catch (Exception e) {
            log.warn("{} findUserInRole 查询在某角色中的用户列表(分页)异常 入参0:{}", CLASS_NAME, JSON.toJSON(vo));
            log.error(e.getMessage(), e);
            return new PageInfo<>(new ArrayList<>());
        }
    }

    /**
     * 把用户从某角色中移除
     *
     * @param roleUser
     * @return
     */
    @Override
    @Transactional(rollbackFor = {BusinessException.class}, propagation = Propagation.REQUIRED)
    public Result deleteRoleUser(RoleUser roleUser) {

        try {

            boolean result = roleMapper.deleteRoleUser(roleUser) > 0;
            log.info("{} deleteRoleUser 把用户从某角色中移除 入参0:{} 结果:{}", CLASS_NAME, JSON.toJSON(roleUser), result);

            return new Result(result);
        } catch (Exception e) {
            log.warn("{} deleteRoleUser 把用户从某角色中移除异常 入参0:{}", CLASS_NAME, JSON.toJSON(roleUser));
            log.error(e.getMessage(), e);
            throw new BusinessException("移除用户失败");
        }

    }

    /**
     * 查询还未加入到某角色中的用户列表(分页)
     *
     * @param vo
     * @return
     */
    @Override
    public PageInfo<User> findUserNotInRole(QueryRoleUserVO vo) {

        try {

            // 处理入参
            if (StringUtils.isEmpty(vo.getDisablePaging()) || !vo.getDisablePaging()) {
                PageHelper.startPage(vo.getPageNum(), vo.getPageSize());
            }
            vo.setWord(StringUtils.isEmpty(vo.getWord()) ? null : "%" + vo.getWord() + "%");

            List<User> notInRole = roleMapper.findUserNotInRole(vo);
            log.info("{} findUserNotInRole 查询还未加入到某角色中的用户列表(分页) 入参0:{} 结果0:{}", CLASS_NAME, JSON.toJSON(vo), JSON.toJSON(notInRole));

            return new PageInfo<>(notInRole);
        } catch (Exception e) {
            log.warn("{} findUserNotInRole 查询还未加入到某角色中的用户列表(分页)异常 入参0:{}", CLASS_NAME, JSON.toJSON(vo));
            log.error(e.getMessage(), e);
            return new PageInfo<>(new ArrayList<>());
        }
    }

    /**
     * 分配某用户到某角色中
     *
     * @param roleUser
     * @return
     */
    @Override
    @Transactional(rollbackFor = {BusinessException.class}, propagation = Propagation.REQUIRED)
    public Result insertRoleUser(RoleUser roleUser) {

        try {

            boolean result = roleMapper.insertRoleUser(roleUser) > 0;
            log.info("{} insertRoleUser 分配某用户到某角色中 入参0:{} 结果0:{}", CLASS_NAME, JSON.toJSON(roleUser), result);

            return new Result(result);
        } catch (Exception e) {
            log.warn("{} insertRoleUser 分配某用户到某角色中异常 入参0:{}", CLASS_NAME, JSON.toJSON(roleUser));
            log.error(e.getMessage(), e);
            throw new BusinessException("分配用户失败");
        }
    }

    /**
     * 批量分配菜单到某角色中
     *
     * @param roleId
     * @param menuIdList
     * @return
     */
    @Override
    @Transactional(rollbackFor = {BusinessException.class}, propagation = Propagation.REQUIRED)
    public Result saveRoleMenu(Object roleId, Object menuIdList) {

        try {

            // 把菜单从某角色中移除
            boolean result = roleMapper.deleteRoleMenu((Integer) roleId) >= 0;
            log.info("{} saveRoleMenu 把菜单从某角色中移除 入参0:{} 结果0:{}", CLASS_NAME, roleId, result);

            // 分配菜单到某角色中 如果菜单列表为空 说明是删除全部菜单 则直接返回true
            List<Integer> list = ObjToListUtil.objToList(menuIdList, Integer.class);
            if (result && CollectionUtils.isEmpty(list)) {
                return new Result(true);
            }

            result = result && roleMapper.insertRoleMenu((Integer) roleId, list) >= 0;
            log.info("{} saveRoleMenu 分配菜单到某角色中 入参0:{} 结果0:{}", CLASS_NAME, JSON.toJSON(menuIdList), result);
            if (!result) {
                throw new BusinessException("分配菜单失败");
            }

            return new Result(true);
        } catch (Exception e) {
            log.warn("{} saveRoleMenu 批量分配菜单到某角色中异常 入参0:{} 1:{}", CLASS_NAME, roleId, JSON.toJSON(menuIdList));
            log.error(e.getMessage(), e);
            throw new BusinessException("分配菜单失败");
        }
    }

}
